/**
 * Description:
 * Class Name:Printer
 * Date:2022/1/30 15:16
 *
 * @author LTisme
 * @version JAVA17
 */
package 疯狂Java讲义.第6章_面向对象_下._6_6_接口_经Java9改进;

interface Product{
    // 没有static，没有private，没有default，那它就是一个抽象实例方法
    int getProduceTime();

    default void pp(){
        System.out.println("我是Product的默认pp方法");
    }
}

// 让Printer类实现Output 和 Product 接口，实现则用implements 关键字，比起继承只能获得成员变量、抽象实例方法，多获得了个默认方法（相当于实例方法）
public class Printer implements Output, Product{
    // 获得了接口的成员变量
    private String[] printData = new String[MAX_CACHE_SIZE];
    // 这个是用以记录当前需打印的作业数，也是索引位置
    private int dataNum = 0;

    // 重写Output接口的抽象方法
    @Override
    public void out() {
        // 只要还有作业，就继续打印
        System.out.println("下面开始循环打印>>>");
        while (dataNum > 0){
            System.out.println("打印机打印： " + printData[0]);
            // 把作业队列整体前移一位，并将剩下的作业书减1
            System.arraycopy(printData, 1, printData, 0, --dataNum);
        }
    }

    // 重写Output接口的抽象方法
    @Override
    public void getData(String msg) {
        if (dataNum >= MAX_CACHE_SIZE){
            System.out.println("输出队列已满，添加失败");
        }
        else {
            // 把打印数据添加到队列里，已保存数据的数量+1
            printData[dataNum++] = msg;
        }
    }

    // 重写Product接口的抽象方法
    @Override
    public int getProduceTime() {
        return 45;
    }

    public static void main(String[] args) {
        // 创建一个Printer对象，声明为Output使用
        Output o = new Printer();
        o.getData("book1");
        o.getData("book2");
        o.out();
        o.getData("book3");
        o.getData("book4");
        o.out();

        // 调用Output接口中定义的默认方法
        o.print("孙悟空", "猪八戒", "白骨精");
        o.test();

        // 创建一个Printer对象，声明为Product使用
        Product p = new Printer();
        System.out.println(p.getProduceTime());

        // 所有接口类型的引用变量都可以直接赋给Object类型的变量
        Object obj = p;

        // 默认方法能通过实现类对象来调用，当然在实现类中也可以重写接口中的默认方法
        p.pp();
    }
}
